package com.kcyu.sfhinvoice.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kcyu.sfhinvoice.domain.FileDO;
import com.kcyu.sfhinvoice.domain.Invoice;
import com.kcyu.sfhinvoice.domain.InvoiceTrack;
import com.kcyu.sfhinvoice.domain.User;
import com.kcyu.sfhinvoice.service.FileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

@RestController
@Api(tags = "文件管理")
@RequestMapping("/file")
public class FileController {

    @Autowired
    private FileService fileService;

    @PostMapping("upload")
    @ApiOperation(value = "上传文件")
    public SaResult upload(@RequestParam("file") MultipartFile file, @RequestParam("modelCode") String modelCode, @RequestParam("busiKey") String busiKey) {
        FileDO upload = fileService.upload(file, modelCode, busiKey);
        return SaResult.data(upload);
    }

    @GetMapping("previewFile")
    @ApiOperation(value = "预览文件")
    public SaResult previewFile(@RequestParam("fileId") String fileId, HttpServletResponse response) {
        FileDO fileDO = fileService.getById(fileId);
        if (fileDO == null) {
            return SaResult.error("文件不存在");
        }
        String filePath = fileDO.getFilePath();
        File file = new File(filePath);
        if (!file.exists()) {
            return SaResult.error("文件在系统找不到");
        }

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            if(fileDO.getFileType().equals("pdf")) {
                response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(fileDO.getFileName(), "UTF-8"));
                response.setContentType("application/pdf");
            } else {
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileDO.getFileName(), "UTF-8"));
                response.setContentType("application/octet-stream");
            }

            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return null;
    }

    @GetMapping("downloadFile")
    @ApiOperation(value = "下载文件")
    public SaResult downloadFile(@RequestParam("fileId") String fileId, HttpServletResponse response) {
        FileDO fileDO = fileService.getById(fileId);
        fileDO.setDownloadCount(fileDO.getDownloadCount() + 1);
        fileService.updateById(fileDO);

        // 添加轨迹
        QueryWrapper<Invoice> invoiceQueryWrapper = new QueryWrapper<>();
        invoiceQueryWrapper.eq("file_key", fileDO.getBusiKey());
        Invoice invoice = new Invoice().selectOne(invoiceQueryWrapper);
        InvoiceTrack invoiceTrack = new InvoiceTrack();
        invoiceTrack.setInvoiceId(invoice.getId());
        invoiceTrack.setStatus("HANDLE");
        invoiceTrack.setPayload("下载文件：" + fileDO.getFileName());
        invoiceTrack.setUser(new User().selectById(StpUtil.getLoginIdAsInt()).getUsername());
        invoiceTrack.insert();

        if (fileDO.getId() == null) {
            return SaResult.error("文件不存在");
        }
        String filePath = fileDO.getFilePath();
        File file = new File(filePath);
        if (!file.exists()) {
            return SaResult.error("文件在系统找不到");
        }

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileDO.getFileName(), "UTF-8"));
            response.setContentType("application/octet-stream");

            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return null;
    }

    @PostMapping("queryFile")
    @ApiOperation(value = "查询文件")
    public SaResult queryFile(@RequestParam("modelCode") String modelCode, @RequestParam("busiKey") String busiKey) {
        List<FileDO> fileDOS = fileService.queryFile(modelCode, busiKey);
        return SaResult.data(fileDOS);
    }

    @PostMapping("removeFile")
    @ApiOperation(value = "删除文件")
    public SaResult removeFile(@RequestParam("fileId") String fileId) {
        boolean b = fileService.removeFile(fileId);
        return SaResult.data(b);
    }


    @PostMapping("uploadAsset")
    @ApiOperation(value = "上传评论资源")
    public SaResult uploadAsset(@RequestParam("file") MultipartFile file) {
        String filePath = fileService.uploadAsset(file);
        return SaResult.data(filePath);
    }

    @GetMapping("assets/{filePath}")
    @ApiOperation(value = "获取评论资源")
    public void getAssets(@PathVariable String filePath, HttpServletResponse response) {
        fileService.getAssets(filePath, response);
    }

}
